#include <unistd.h>
#include "nemo-sync-prompt-dialog.h"
#include "libnemo-extension/nemo-extension-i18n.h"
#include <sys/wait.h>
#include <sys/types.h>

static GtkWidget *dialog = NULL;
static GtkWidget *window = NULL;

static void
sync_prompt_dialog_hide (GtkWidget *window,
                                             gpointer user_data)
{
    //隐藏窗口
    gtk_window_iconify (GTK_WINDOW (dialog));
}

static void
create_sync_prompt_dialog (const char *title_dialog_text,
                                                const char *primary_text,
                                                const char *sync_text)
{
    GtkWidget *content_area;
    GtkWidget *progress_bar;
    GtkWidget *sync_label;
    GtkWidget *button_minimize;
    GtkWidget *button_box_min;

    const char *button_label;
    if (!window) {
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    }

    if (!dialog) {
        dialog = gtk_dialog_new ();
    }

    sync_label = gtk_label_new (primary_text);
    content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));

    gtk_window_set_title (GTK_WINDOW (dialog), title_dialog_text);

    gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 100);
    //进度条
    progress_bar = gtk_progress_bar_new ();
    // text
    PangoFontDescription *sync_text_change = pango_font_description_from_string ("Bold");
    pango_font_description_set_size (sync_text_change, 12 * PANGO_SCALE);
    gtk_widget_modify_font (GTK_WIDGET (progress_bar), sync_text_change);
    pango_font_description_free (sync_text_change);

    // button
    button_label = _("Hide");
    button_minimize = gtk_button_new_with_label (button_label);
    gtk_button_set_label (GTK_BUTTON (button_minimize), button_label);

    gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (progress_bar), TRUE);
    gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress_bar), sync_text);
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), 0.0);

    gtk_box_pack_start (GTK_BOX (content_area), progress_bar, TRUE, TRUE, 0);
    gtk_box_pack_start (GTK_BOX (content_area), sync_label, TRUE, TRUE, 0);

    button_box_min = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box_min), GTK_BUTTONBOX_END);
    gtk_box_pack_start (GTK_BOX (button_box_min), button_minimize, FALSE, FALSE, 0);

    gtk_box_pack_start (GTK_BOX (content_area), button_box_min, FALSE, FALSE, 0);

    gtk_widget_set_margin_start (button_box_min, 100);

    g_signal_connect (button_minimize, "clicked", G_CALLBACK (sync_prompt_dialog_hide), NULL);
}

static void
update_progress_bar (GtkDialog *dialog,
                                      gdouble fraction)
{
    GtkWidget *content_area;
    GList *children = NULL;
    GList *child = NULL;
    GtkWidget *progress_bar;
    const char *done_text;

    content_area = gtk_dialog_get_content_area (dialog);
    children = gtk_container_get_children (GTK_CONTAINER (content_area));
    for (child = children; child != NULL; child = child->next) {
        const gchar *child_type = g_type_name (G_TYPE_FROM_INSTANCE (child->data));
        if (g_strcmp0(child_type, "GtkProgressBar") == 0) {
            progress_bar = GTK_WIDGET (child->data);
        }
    }

    done_text = _("Data synchronization is going...");
    gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress_bar), done_text);
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), fraction);
}

static void
update_progress_bar_sync_done (GtkDialog *dialog,
                                                          gdouble fraction)
{
    GtkWidget *content_area;
    GList *children = NULL;
    GList *child = NULL;
    GtkWidget *progress_bar;
    const char *done_text;

    content_area = gtk_dialog_get_content_area (dialog);
    children = gtk_container_get_children (GTK_CONTAINER (content_area));
    for (child = children; child != NULL; child = child->next) {
        const gchar *child_type = g_type_name (G_TYPE_FROM_INSTANCE (child->data));
        if (g_strcmp0 (child_type, "GtkProgressBar") == 0) {
            progress_bar = GTK_WIDGET (child->data);
        }
    }

    done_text = _("Data synchronization is done");

    gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress_bar), done_text);
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), fraction);
}

static gboolean
on_timeout_callback (gpointer user_data)
{
    gtk_widget_destroy (dialog);
    window = NULL;
    dialog = NULL;

    return FALSE;
}

static void
sync_prompt_dialog_destroy (GtkDialog *dialog,
                                                  gint response_id,
                                                  gpointer user_data)
{
    update_progress_bar_sync_done (dialog, 1.0);
    while (gtk_events_pending ())
        gtk_main_iteration ();
    g_timeout_add (300,
                               on_timeout_callback,
                               NULL);
}

static void
show_sync_prompt_dialog ()
{
    const char *title_dialog_text;
    const char *primary_text;
    const char *sync_text;

    title_dialog_text = _("Syncing..., one moment please");
    primary_text = _("Writing to cache, please don't unplug the removable device, otherwise data will be lost.");
    sync_text = _("Syncing data to device...");

    create_sync_prompt_dialog (title_dialog_text, primary_text, sync_text);
    gtk_widget_show_all (dialog);
    g_signal_connect (dialog,
                                   "response",
                                   G_CALLBACK (sync_prompt_dialog_destroy), NULL);

    //显示进度条增加过程
    gint i;
    if (dialog) {
        gdouble tmpid = 0.0;
        gdouble add_val = 0.1;
        for (i = 1; i <= 9; i++) {
            tmpid = (gdouble) (tmpid + add_val);
            update_progress_bar (GTK_DIALOG (dialog), tmpid);
            while (gtk_events_pending ())
                gtk_main_iteration ();
            usleep (10000);
        }
    }

    gtk_dialog_run (GTK_DIALOG (dialog));
}

static gboolean
idle_callback (gpointer user_data)
{
    show_sync_prompt_dialog ();

    return FALSE;
}

static void
show_sync_prompt_dialog_idle ()
{
    g_timeout_add (50, idle_callback, NULL);
}

static void
sync_prompt_dialog_sync_done ()
{
    if (dialog)
    {
        g_signal_emit_by_name (dialog, "response");
    }
}

static gboolean
on_sync_done_timeout (gpointer user_data)
{

    sync_prompt_dialog_sync_done ();
    return FALSE;
}
void sync_and_show_dialog ()
{
    show_sync_prompt_dialog_idle ();
    sync ();
    g_timeout_add (50,
                               on_sync_done_timeout,
                               NULL);
}